package demo04;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import static org.objectweb.asm.Opcodes.ASM9;

public class RemoveMethodPrintVisitor extends ClassVisitor {
    protected RemoveMethodPrintVisitor(int api, ClassVisitor classVisitor) {
        super(api, classVisitor);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv =  super.visitMethod(access, name, descriptor, signature, exceptions);
        if(null != mv && !"<init>".equals(name)){
            mv = new RemoveMethodPrintAdapter(ASM9,mv);
        }
        return mv;
    }

    class RemoveMethodPrintAdapter extends MethodVisitor {
        protected RemoveMethodPrintAdapter(int api, MethodVisitor methodVisitor) {
            super(api, methodVisitor);
        }

       @Override
        public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {

                System.out.println("Field opcode="+opcode+" owner="+owner+" name= "+name+" descriptor="+descriptor);
                if(opcode == Opcodes.GETSTATIC && owner.equals("java/lang/System") && name.equals("out") && descriptor.equals("Ljava/io/PrintStream;") ){
                    return;
                }


           super.visitFieldInsn(opcode, owner, name, descriptor);

       }

        //这个操作的就是方法里边的方法
        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
            System.out.println("opcode="+opcode+" owner="+owner+" name= "+name+" descriptor="+descriptor+" isInterface="+isInterface);
            if(opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/io/PrintStream")
                    && name.equals("println") && descriptor.equals("(Ljava/lang/String;)V") ){
                System.out.println("opcode="+opcode+" owner="+owner+" name= "+name+" descriptor="+descriptor+" isInterface="+isInterface);
                return;
            }
            super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
        }


        @Override
        public void visitLdcInsn(Object value) {
            return;
           // super.visitLdcInsn(value);
        }

        @Override
        public void visitVarInsn(int opcode, int varIndex) {
            System.out.println("opcode "+ opcode + " varIndex=" + varIndex);
            if(opcode == Opcodes.ISTORE && varIndex == 3){
                super.visitVarInsn(opcode, varIndex);
                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
                return;
            }
            super.visitVarInsn(opcode, varIndex);
        }

        @Override
        public void visitInsn(int opcode) {
            System.out.println(opcode);
            super.visitInsn(opcode);
        }
    }


}
